package com.hbnu.tangyalu.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo {
    public static void main(String[] args)  throws  Exception{
//       1.1方法通过类名获取
        Class<?> claz= Person.class;
//        1.2通过对象获取.getClass
        Person p=new Person();
        Class<?> clazz= p.getClass();
//        1.3通过字符串获取
        Class<?> clazzz= Class.forName("com.hbnu.tangyalu.reflect.Person");
        System.out.println("-----------------------");
        System.out.println("2.1获取所有的公共构造方法");
        Constructor<?>[] constructors= claz.getConstructors();
        System.out.println("所有公共构造方法的个数："+constructors.length+"个，分别是：");
        for (Constructor<?> constructor: constructors) {
            System.out.println("方法名："+constructor.getName()+"参数个数"+constructor.getParameterCount()+"参数类型"+constructor.getParameterTypes());
            Class<?>[] parameterTypes =constructor.getParameterTypes();
            for (Class<?> parameterType: parameterTypes) {
                System.out.print(parameterType.getName()+"\t");
            }
            System.out.println();
        }
        System.out.println("获取所有的构造方法，（包括私有的）");
        Constructor<?>[] declaredconstructors= clazz.getDeclaredConstructors();
        System.out.println("所有构造方法的个数："+declaredconstructors.length+"个，分别是：");
        for (Constructor<?> declaredconstructor: declaredconstructors) {
            System.out.println("方法名："+declaredconstructor.getName()+"参数个数"+declaredconstructor.getParameterCount()+"参数类型"+declaredconstructor.getParameterTypes());
            Class<?>[] parameterTypes =declaredconstructor.getParameterTypes();
            for (Class<?> parameterType: parameterTypes) {
                System.out.print(parameterType.getName()+"\t");
            }
            System.out.println();
        }
        System.out.println("2.3获取指定的公共构造方法，并进行实例化");
        Constructor<?> constructor=clazz.getConstructor(String.class,int.class);
        Person person1=(Person) constructor.newInstance("张三",20);
        Person person2=(Person) clazzz.newInstance();

        System.out.println("通过反射获取构造方法并创建的对象"+person1);
//        3.获取成员属性
        System.out.println("3.1获取公共成员属性");
        Field[] fields=clazz.getFields();
        System.out.println("所有公共成员属性的个数"+fields.length+"个，分别是：");
        for (Field field: fields
             ) {
            System.out.println("属性类型"+field.getType().getName()+"，属性名："+field.getName());

        }

        System.out.println("3.2获取所有公共成员的属性，包括私有的");
        Field[] declaredFields=clazz.getDeclaredFields();
        System.out.println("所有公共成员属性的个数"+fields.length+"个，分别是：");
        for (Field declaredfield: declaredFields
        ) {
            System.out.println("属性类型"+declaredfield.getType().getName()+"，属性名："+declaredfield.getName());

        }
        System.out.println("3.2获取指定公共成员的属性");
        Field address=clazz.getField("address");
        address.set(person2,"北京");
        System.out.println("通过反射获取公共成员属性并赋值:"+person2.address);
        System.out.println("3.4获取指定的成员属性（包括私有的）");
        Field age=clazz.getDeclaredField("age");
        age.setAccessible(true);
        age.set(person2,20);
        System.out.println("通过反射获取成员属性并赋值"+person2.getAge());
        System.out.println("4.1获取所有的公共成员的方法(包括继承过来的方法）");
        Method[] methods=clazz.getMethods();
        System.out.println("所有公共成员方法的个数："+methods.length+"个，分别是：");
        for (Method method: methods) {
            System.out.println("方法返回值："+method.getReturnType().getName()+"方法名"+method.getName()+"参数个数"+method.getParameterCount()+"参数类型"+method.getParameterTypes());
            Class<?>[] parameterTypes =method.getParameterTypes();
            for (Class<?> parameterType: parameterTypes) {
                System.out.print(parameterType.getName()+"\t");
            }
            System.out.println();
        }

        System.out.println("4.2获取所有的公共成员的方法(包括私有的）");
        Method[] declaredMethods=clazz.getDeclaredMethods();
        System.out.println("所有成员方法的个数："+declaredconstructors.length+"个，分别是：");
        for (Method declaredmethod: declaredMethods) {
            System.out.println("方法名："+declaredmethod.getName()+"参数个数"+declaredmethod.getParameterCount()+"参数类型"+declaredmethod.getParameterTypes());
            Class<?>[] parameterTypes =declaredmethod.getParameterTypes();
            for (Class<?> parameterType: parameterTypes) {
                System.out.print(parameterType.getName()+"\t");
            }
            System.out.println();
        }

        System.out.println("4.3获取指定的公共成员的方法");
        Method method=clazz.getMethod("sayHi");
        method.invoke(method);
        System.out.println("4.4获取指定的公共成员的方法（包括私有的）");
        Method method1=clazz.getDeclaredMethod("method", String.class);
        method1.setAccessible(true);
        String result=(String) method1.invoke(person2,"反射方法调用method()方法");
        System.out.println("反射方法调用method()方法的调用 ");

    }
}
